/**
 * Copyright (c) 2017,安徽皖通科技股份有限公司 All rights reserved.
 *
 * @data:2017年10月17日
 * @author:MaShibo
 */
package com.wttech.dzzf.process.service.transaction;

import com.wttech.dzzf.process.dao.ReimburseInfosDao;
import com.wttech.dzzf.process.dao.TransferUserInfoDao;
import com.wttech.dzzf.process.model.Organization;
import com.wttech.dzzf.process.model.transaction.Reimburse;
import com.wttech.dzzf.process.model.transaction.ReimburseDTO;
import com.wttech.dzzf.process.service.base.BaseInfoService;
import com.wttech.dzzf.process.service.user.UserInfosCreatorService;
import com.wttech.dzzf.process.util.BusinessUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;

import static com.wttech.dzzf.process.constant.UserConstants.DEFAULT_CHANNELID;

/**
 * 退款信息创建服务实现
 *
 * @author MaShibo
 * @date 2017年10月17日
 */
@Service
public class ReimburseInfosCreatorService {


    private static final Logger LOGGER = LoggerFactory.getLogger(ReimburseInfosCreatorService.class);

    /**
     * 默认时间格式
     */
    private static final String DEFAULT_DATETIME_PATTERN = "yyyyMMddHHmmss";

    private static final BigDecimal DEFAULT_FEN_VALUE = new BigDecimal("100");

    private static final int DEFAULT_SEQNO_LENGTH = 2;

    @Resource
    private ReimburseInfosDao reimburseInfosDao;

    @Resource
    private TransferUserInfoDao transferUserInfoDao;

    @Resource
    private ThreadPoolTaskExecutor executor;

    @Resource
    private BaseInfoService baseInfoService;

    @Resource
    private UserInfosCreatorService userInfosCreatorService;

    private Map<String, Integer> seqNoMap = new ConcurrentHashMap<>();

    private void createReimburseInfos() {
        List<ReimburseDTO> infos = reimburseInfosDao.queryReimburseInfos();
        LOGGER.info("共{}条待处理记录", infos.size());
        List<Future<Void>> futures = new ArrayList<>(infos.size());
        infos.forEach(info -> futures.add(executor.submit(() -> {
            try {
                processSingleReimburse(info);
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
            return null;
        })));
        baseInfoService.getFutureResult(futures);
        LOGGER.info("退款数据处理完毕");
        executor.shutdown();
    }


    /**
     * 处理单独的退款记录信息
     *
     * @param info 退款记录
     */
    private void processSingleReimburse(ReimburseDTO info) {
        String clientNo = info.getClientNo();
        Organization org = transferUserInfoDao.queryOrganizationByNo(clientNo);

        if (org == null) {
            LOGGER.error("网点编号【{}】，无对应的组织机构信息", clientNo);
            return;
        }

        String channelId = StringUtils.isBlank(org.getChannelId()) ? DEFAULT_CHANNELID : org.getChannelId();
        String cardId = info.getCardNetId() + info.getEcardNo();

        //创建卡片相关的数据
        userInfosCreatorService.processCardAboutInfos(cardId);

        Reimburse rb = new Reimburse();

        String id = buildReimburseId(org.getAgencyType(), info.getRefundOn(), channelId);
        rb.setId(id);

        String userId;
        try {
            userId = reimburseInfosDao.queryUserIdByCardId(cardId);
        } catch (Exception e) {
            LOGGER.error("卡片【{}】，无对应的客户信息", cardId);
            return;
        }
        rb.setUserId(userId);
        rb.setCardId(cardId);
        rb.setFee(info.getFee().multiply(DEFAULT_FEN_VALUE).longValue());
        try {
            transferUserInfoDao.createTestObjcet(rb);
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            LOGGER.info("错误的退款信息{}", rb.toString());
        }
    }

    /**
     * 构建退款记录ID
     *
     * @param agencyType 客服合作机构类型
     * @param refundOn   退款日期
     * @param channelId  渠道ID
     * @return 退款记录ID
     */
    private String buildReimburseId(Integer agencyType, Date refundOn, String channelId) {
        Integer channelType = BusinessUtils.convertChannelType(agencyType);
        String transTime = DateFormatUtils.format(refundOn, DEFAULT_DATETIME_PATTERN);
        Integer exserialNum = baseInfoService.getExserialNum(transTime, seqNoMap);
        StringBuilder exserialStr = new StringBuilder(exserialNum.toString());
        while (exserialStr.length() < DEFAULT_SEQNO_LENGTH) {
            exserialStr.insert(0, '0');
        }
        return channelType.toString() + channelId + transTime + exserialStr;
    }


    public static void main(String[] args) {
        @SuppressWarnings("resource")
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ReimburseInfosCreatorService service = context.getBean(ReimburseInfosCreatorService.class);
        service.createReimburseInfos();
    }
}
